x86 hvm: Fix #UD interception.
authorKeir Fraser <keir.fraser@citrix.com>
Wed, 1 Jul 2009 13:58:31 +0000 (14:58 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Wed, 1 Jul 2009 13:58:31 +0000 (14:58 +0100)
 * Interception should be standard part of HVM_TRAP_MASK
 * Failed intercept should quietly forward #UD to the guest

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
xen/arch/x86/hvm/svm/svm.c
xen/arch/x86/hvm/svm/vmcb.c
xen/arch/x86/hvm/vmx/vmcs.c
xen/arch/x86/hvm/vmx/vmx.c
xen/include/asm-x86/hvm/hvm.h

index aae51c0e05c7a7db61c4864e195aaef75bc7c963..be78c65555e4ef461c1014a3bae2198029338da1 100644 (file)
@@ -1226,24 +1226,16 @@ static void svm_vmexit_ud_intercept(struct cpu_user_regs *regs)
     switch ( rc )
     {
     case X86EMUL_UNHANDLEABLE:
-        gdprintk(XENLOG_WARNING,
-                 "instruction emulation failed @ %04x:%lx: "
-                 "%02x %02x %02x %02x %02x %02x\n",
-                 hvmemul_get_seg_reg(x86_seg_cs, &ctxt)->sel,
-                 ctxt.insn_buf_eip,
-                 ctxt.insn_buf[0], ctxt.insn_buf[1],
-                 ctxt.insn_buf[2], ctxt.insn_buf[3],
-                 ctxt.insn_buf[4], ctxt.insn_buf[5]);
-         return;
+        svm_inject_exception(TRAP_invalid_op, HVM_DELIVER_NO_ERROR_CODE, 0);
+        break;
     case X86EMUL_EXCEPTION:
         if ( ctxt.exn_pending )
             hvm_inject_exception(ctxt.exn_vector, ctxt.exn_error_code, 0);
-        break;
+        /* fall through */
     default:
+        hvm_emulate_writeback(&ctxt);
         break;
     }
-
-    hvm_emulate_writeback(&ctxt);
 }
 
 static void wbinvd_ipi(void *info)
index d1b00093b88c5a10bff5c8829122b0681de5ee5b..d83fdc185aa60d3f09443c18a705258e23e2e16d 100644 (file)
@@ -227,8 +227,7 @@ static int construct_vmcb(struct vcpu *v)
 
     vmcb->exception_intercepts =
         HVM_TRAP_MASK
-        | (1U << TRAP_no_device)
-        | (1U << TRAP_invalid_op);
+        | (1U << TRAP_no_device);
 
     if ( paging_mode_hap(v->domain) )
     {
index 881a9a832b74b4e9f014f3b976e3fb1acbad7724..cd6e44073da5270694d92744a6a5483a7702aa6f 100644 (file)
@@ -679,8 +679,7 @@ static int construct_vmcs(struct vcpu *v)
     __vmwrite(EXCEPTION_BITMAP,
               HVM_TRAP_MASK
               | (paging_mode_hap(d) ? 0 : (1U << TRAP_page_fault))
-              | (1U << TRAP_no_device)
-              | (1U << TRAP_invalid_op));
+              | (1U << TRAP_no_device));
 
     v->arch.hvm_vcpu.guest_cr[0] = X86_CR0_PE | X86_CR0_ET;
     hvm_update_guest_cr(v, 0);
index b5a74965ad0c3c96a4296e1de8cfecb9052b2927..fdfcb8d2e6738e5bcc3e58033f6badbb05e49d01 100644 (file)
@@ -2258,34 +2258,26 @@ asmlinkage void vmx_enter_realmode(struct cpu_user_regs *regs)
 
 static void vmx_vmexit_ud_intercept(struct cpu_user_regs *regs)
 {
-     struct hvm_emulate_ctxt ctxt;
-     int rc;
-     hvm_emulate_prepare(&ctxt, regs);
-     rc = hvm_emulate_one(&ctxt);
-     switch ( rc )
-     {
-     case X86EMUL_UNHANDLEABLE:
-         gdprintk(XENLOG_WARNING,
-                  "instruction emulation failed @ %04x:%lx: "
-                  "%02x %02x %02x %02x %02x %02x\n",
-                  hvmemul_get_seg_reg(x86_seg_cs, &ctxt)->sel,
-                  ctxt.insn_buf_eip,
-                  ctxt.insn_buf[0], ctxt.insn_buf[1],
-                  ctxt.insn_buf[2], ctxt.insn_buf[3],
-                  ctxt.insn_buf[4], ctxt.insn_buf[5]);
-          return;
-     case X86EMUL_EXCEPTION:
-         if ( ctxt.exn_pending )
-             hvm_inject_exception(ctxt.exn_vector, ctxt.exn_error_code, 0);
-         break;
-     default:
-         break;
-     }
-     hvm_emulate_writeback(&ctxt);
+    struct hvm_emulate_ctxt ctxt;
+    int rc;
+
+    hvm_emulate_prepare(&ctxt, regs);
+
+    rc = hvm_emulate_one(&ctxt);
+
+    switch ( rc )
+    {
+    case X86EMUL_UNHANDLEABLE:
+        vmx_inject_hw_exception(TRAP_invalid_op, HVM_DELIVER_NO_ERROR_CODE);
+        break;
+    case X86EMUL_EXCEPTION:
+        if ( ctxt.exn_pending )
+            hvm_inject_exception(ctxt.exn_vector, ctxt.exn_error_code, 0);
+        /* fall through */
+    default:
+        hvm_emulate_writeback(&ctxt);
+        break;
+    }
 }
 
 asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs)
index 4557cd0dcd5cf918bb2ecfdac85b7111ac953bea..1a905272b09f69544646d3f8446d8a2a7039115f 100644 (file)
@@ -268,7 +268,7 @@ static inline int hvm_do_pmu_interrupt(struct cpu_user_regs *regs)
         X86_CR4_OSFXSR | X86_CR4_OSXMMEXCPT)))
 
 /* These exceptions must always be intercepted. */
-#define HVM_TRAP_MASK (1U << TRAP_machine_check)
+#define HVM_TRAP_MASK ((1U << TRAP_machine_check) | (1U << TRAP_invalid_op))
 
 /*
  * x86 event types. This enumeration is valid for: